home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / src-glu / mipmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-27  |  16.4 KB  |  699 lines

  1. /* $Id: mipmap.c,v 1.1 1996/09/27 01:19:39 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.0
  6.  * Copyright (C) 1995-1996  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: mipmap.c,v $
  26.  * Revision 1.1  1996/09/27 01:19:39  brianp
  27.  * Initial revision
  28.  *
  29.  */
  30.  
  31.  
  32. #include <assert.h>
  33. #include <math.h>
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include "gluP.h"
  37.  
  38.  
  39.  
  40. /*
  41.  * Compute ceiling of integer quotient of A divided by B:
  42.  */
  43. #define CEILING( A, B )  ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
  44.  
  45.  
  46.  
  47. #define EPSILON 0.001
  48.  
  49.  
  50.  
  51.  
  52. GLint gluScaleImage( GLenum format,
  53.                      GLint widthin, GLint heightin,
  54.                      GLenum typein, const void *datain,
  55.                      GLint widthout, GLint heightout,
  56.                      GLenum typeout, void *dataout )
  57. {
  58.    GLuint components, i, j, k;
  59.    GLfloat *tempin, *tempout;
  60.    GLfloat sx, sy;
  61.    GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels;
  62.    GLint packrowlength, packalignment, packskiprows, packskippixels;
  63.    GLint sizein, sizeout;
  64.    GLint rowstride, rowlen;
  65.  
  66.  
  67.    /* Determine number of components per pixel */
  68.    switch (format) {
  69.       case GL_COLOR_INDEX:
  70.       case GL_STENCIL_INDEX:
  71.       case GL_DEPTH_COMPONENT:
  72.       case GL_RED:
  73.       case GL_GREEN:
  74.       case GL_BLUE:
  75.       case GL_ALPHA:
  76.       case GL_LUMINANCE:
  77.          components = 1;
  78.      break;
  79.       case GL_LUMINANCE_ALPHA:
  80.      components = 2;
  81.      break;
  82.       case GL_RGB:
  83.      components = 3;
  84.      break;
  85.       case GL_RGBA:
  86.      components = 4;
  87.      break;
  88.       default:
  89.      return GLU_INVALID_ENUM;
  90.    }
  91.  
  92.    /* Determine bytes per input datum */
  93.    switch (typein) {
  94.       case GL_UNSIGNED_BYTE:    sizein = sizeof(GLubyte);    break;
  95.       case GL_BYTE:        sizein = sizeof(GLbyte);    break;
  96.       case GL_UNSIGNED_SHORT:    sizein = sizeof(GLushort);    break;
  97.       case GL_SHORT:        sizein = sizeof(GLshort);    break;
  98.       case GL_UNSIGNED_INT:    sizein = sizeof(GLuint);    break;
  99.       case GL_INT:        sizein = sizeof(GLint);        break;
  100.       case GL_FLOAT:        sizein = sizeof(GLfloat);    break;
  101.       case GL_BITMAP:
  102.      /* not implemented yet */
  103.       default:
  104.      return GL_INVALID_ENUM;
  105.    }
  106.  
  107.    /* Determine bytes per output datum */
  108.    switch (typeout) {
  109.       case GL_UNSIGNED_BYTE:    sizeout = sizeof(GLubyte);    break;
  110.       case GL_BYTE:        sizeout = sizeof(GLbyte);    break;
  111.       case GL_UNSIGNED_SHORT:    sizeout = sizeof(GLushort);    break;
  112.       case GL_SHORT:        sizeout = sizeof(GLshort);    break;
  113.       case GL_UNSIGNED_INT:    sizeout = sizeof(GLuint);    break;
  114.       case GL_INT:        sizeout = sizeof(GLint);    break;
  115.       case GL_FLOAT:        sizeout = sizeof(GLfloat);    break;
  116.       case GL_BITMAP:
  117.      /* not implemented yet */
  118.       default:
  119.      return GL_INVALID_ENUM;
  120.    }
  121.  
  122.    /* Get glPixelStore state */
  123.    glGetIntegerv( GL_UNPACK_ROW_LENGTH, &unpackrowlength );
  124.    glGetIntegerv( GL_UNPACK_ALIGNMENT, &unpackalignment );
  125.    glGetIntegerv( GL_UNPACK_SKIP_ROWS, &unpackskiprows );
  126.    glGetIntegerv( GL_UNPACK_SKIP_PIXELS, &unpackskippixels );
  127.    glGetIntegerv( GL_PACK_ROW_LENGTH, &packrowlength );
  128.    glGetIntegerv( GL_PACK_ALIGNMENT, &packalignment );
  129.    glGetIntegerv( GL_PACK_SKIP_ROWS, &packskiprows );
  130.    glGetIntegerv( GL_PACK_SKIP_PIXELS, &packskippixels );
  131.  
  132.    /* Allocate storage for intermediate images */
  133.    tempin = (GLfloat *) malloc( widthin * heightin
  134.                     * components * sizeof(GLfloat) );
  135.    if (!tempin) {
  136.       return GLU_OUT_OF_MEMORY;
  137.    }
  138.    tempout = (GLfloat *) malloc( widthout * heightout
  139.                       * components * sizeof(GLfloat) );
  140.    if (!tempout) {
  141.       free( tempin );
  142.       return GLU_OUT_OF_MEMORY;
  143.    }
  144.  
  145.  
  146.    /*
  147.     * Unpack the pixel data and convert to floating point
  148.     */
  149.  
  150.    if (unpackrowlength>0) {
  151.       rowlen = unpackrowlength;
  152.    }
  153.    else {
  154.       rowlen = widthin;
  155.    }
  156.    if (sizein >= unpackalignment) {
  157.       rowstride = components * rowlen;
  158.    }
  159.    else {
  160.       rowstride = unpackalignment/sizein
  161.             * CEILING( components * rowlen * sizein, unpackalignment );
  162.    }
  163.  
  164.    switch (typein) {
  165.       case GL_UNSIGNED_BYTE:
  166.      k = 0;
  167.      for (i=0;i<heightin;i++) {
  168.         GLubyte *ubptr = (GLubyte *) datain
  169.                        + i * rowstride
  170.                + unpackskiprows * rowstride
  171.                + unpackskippixels * components;
  172.         for (j=0;j<widthin*components;j++) {
  173.            tempin[k++] = (GLfloat) *ubptr++;
  174.         }
  175.      }
  176.      break;
  177.       case GL_BYTE:
  178.      k = 0;
  179.      for (i=0;i<heightin;i++) {
  180.         GLbyte *bptr = (GLbyte *) datain
  181.                      + i * rowstride
  182.              + unpackskiprows * rowstride
  183.              + unpackskippixels * components;
  184.         for (j=0;j<widthin*components;j++) {
  185.            tempin[k++] = (GLfloat) *bptr++;
  186.         }
  187.      }
  188.      break;
  189.       case GL_UNSIGNED_SHORT:
  190.      k = 0;
  191.      for (i=0;i<heightin;i++) {
  192.         GLushort *usptr = (GLushort *) datain
  193.                         + i * rowstride
  194.                 + unpackskiprows * rowstride
  195.                 + unpackskippixels * components;
  196.         for (j=0;j<widthin*components;j++) {
  197.            tempin[k++] = (GLfloat) *usptr++;
  198.         }
  199.      }
  200.      break;
  201.       case GL_SHORT:
  202.      k = 0;
  203.      for (i=0;i<heightin;i++) {
  204.         GLshort *sptr = (GLshort *) datain
  205.                       + i * rowstride
  206.               + unpackskiprows * rowstride
  207.               + unpackskippixels * components;
  208.         for (j=0;j<widthin*components;j++) {
  209.            tempin[k++] = (GLfloat) *sptr++;
  210.         }
  211.      }
  212.      break;
  213.       case GL_UNSIGNED_INT:
  214.      k = 0;
  215.      for (i=0;i<heightin;i++) {
  216.         GLuint *uiptr = (GLuint *) datain
  217.                       + i * rowstride
  218.               + unpackskiprows * rowstride
  219.               + unpackskippixels * components;
  220.         for (j=0;j<widthin*components;j++) {
  221.            tempin[k++] = (GLfloat) *uiptr++;
  222.         }
  223.      }
  224.      break;
  225.       case GL_INT:
  226.      k = 0;
  227.      for (i=0;i<heightin;i++) {
  228.         GLint *iptr = (GLint *) datain
  229.                     + i * rowstride
  230.             + unpackskiprows * rowstride
  231.             + unpackskippixels * components;
  232.         for (j=0;j<widthin*components;j++) {
  233.            tempin[k++] = (GLfloat) *iptr++;
  234.         }
  235.      }
  236.      break;
  237.       case GL_FLOAT:
  238.      k = 0;
  239.      for (i=0;i<heightin;i++) {
  240.         GLfloat *fptr = (GLfloat *) datain
  241.                       + i * rowstride
  242.               + unpackskiprows * rowstride
  243.               + unpackskippixels * components;
  244.         for (j=0;j<widthin*components;j++) {
  245.            tempin[k++] = *fptr++;
  246.         }
  247.      }
  248.      break;
  249.       default:
  250.      return GLU_INVALID_ENUM;
  251.    }
  252.  
  253.  
  254.    /*
  255.     * Scale the image!
  256.     */
  257.  
  258.    sx = (GLfloat) widthin / (GLfloat) widthout;
  259.    sy = (GLfloat) heightin / (GLfloat) heightout;
  260.  
  261. /*#define POINT_SAMPLE*/
  262. #ifdef POINT_SAMPLE
  263.    for (i=0;i<heightout;i++) {
  264.       GLint ii = i * sy;
  265.       for (j=0;j<widthout;j++) {
  266.      GLint jj = j * sx;
  267.  
  268.      GLfloat *src = tempin + (ii * widthin + jj) * components;
  269.      GLfloat *dst = tempout + (i * widthout + j) * components;
  270.  
  271.      for (k=0;k<components;k++) {
  272.         *dst++ = *src++;
  273.      }
  274.       }
  275.    }
  276. #else
  277.    if (sx<1.0 && sy<1.0) {
  278.       /* magnify both width and height:  use weighted sample of 4 pixels */
  279.       GLint i0, i1, j0, j1;
  280.       GLfloat alpha, beta;
  281.       GLfloat *src00, *src01, *src10, *src11;
  282.       GLfloat s1, s2;
  283.       GLfloat *dst;
  284.  
  285.       for (i=0;i<heightout;i++) {
  286.      i0 = i * sy;
  287.      i1 = (i+1) * sy - EPSILON;
  288.      alpha = i*sy - i0;
  289.      for (j=0;j<widthout;j++) {
  290.         j0 = j * sx;
  291.         j1 = (j+1) * sx - EPSILON;
  292.         beta = j*sx - j0;
  293.  
  294.         /* compute weighted average of pixels in rect (i0,j0)-(i1,j1) */
  295.         src00 = tempin + (i0 * widthin + j0) * components;
  296.         src01 = tempin + (i0 * widthin + j1) * components;
  297.         src10 = tempin + (i1 * widthin + j0) * components;
  298.         src11 = tempin + (i1 * widthin + j1) * components;
  299.  
  300.         dst = tempout + (i * widthout + j) * components;
  301.  
  302.         for (k=0;k<components;k++) {
  303.            s1 = *src00++ * (1.0-beta) + *src01++ * beta;
  304.            s2 = *src10++ * (1.0-beta) + *src11++ * beta;
  305.            *dst++ = s1 * (1.0-alpha) + s2 * alpha;
  306.         }
  307.      }
  308.       }
  309.    }
  310.    else {
  311.       /* shrink width and/or height:  use an unweighted box filter */
  312.       GLint i0, i1;
  313.       GLint j0, j1;
  314.       GLint ii, jj;
  315.       GLfloat sum, *dst;
  316.  
  317.       for (i=0;i<heightout;i++) {
  318.      i0 = i * sy;
  319.      i1 = (i+1) * sy - EPSILON;
  320.      for (j=0;j<widthout;j++) {
  321.         j0 = j * sx;
  322.         j1 = (j+1) * sx - EPSILON;
  323.  
  324.         dst = tempout + (i * widthout + j) * components;
  325.  
  326.         /* compute average of pixels in the rectangle (i0,j0)-(i1,j1) */
  327.         for (k=0;k<components;k++) {
  328.            sum = 0.0;
  329.            for (ii=i0;ii<=i1;ii++) {
  330.           for (jj=j0;jj<=j1;jj++) {
  331.              sum += *(tempin + (ii * widthin + jj) * components + k);
  332.           }
  333.            }
  334.            sum /= (j1-j0+1) * (i1-i0+1);
  335.            *dst++ = sum;
  336.         }
  337.      }
  338.       }
  339.    }
  340. #endif
  341.  
  342.  
  343.    /*
  344.     * Return output image
  345.     */
  346.  
  347.    if (packrowlength>0) {
  348.       rowlen = packrowlength;
  349.    }
  350.    else {
  351.       rowlen = widthout;
  352.    }
  353.    if (sizeout >= packalignment) {
  354.       rowstride = components * rowlen;
  355.    }
  356.    else {
  357.       rowstride = packalignment/sizeout
  358.             * CEILING( components * rowlen * sizeout, packalignment );
  359.    }
  360.  
  361.    switch (typeout) {
  362.       case GL_UNSIGNED_BYTE:
  363.      k = 0;
  364.      for (i=0;i<heightout;i++) {
  365.         GLubyte *ubptr = (GLubyte *) dataout
  366.                        + i * rowstride
  367.                + packskiprows * rowstride
  368.                + packskippixels * components;
  369.         for (j=0;j<widthout*components;j++) {
  370.            *ubptr++ = (GLubyte) tempout[k++];
  371.         }
  372.      }
  373.      break;
  374.       case GL_BYTE:
  375.      k = 0;
  376.      for (i=0;i<heightout;i++) {
  377.         GLbyte *bptr = (GLbyte *) dataout
  378.                      + i * rowstride
  379.              + packskiprows * rowstride
  380.              + packskippixels * components;
  381.         for (j=0;j<widthout*components;j++) {
  382.            *bptr++ = (GLbyte) tempout[k++];
  383.         }
  384.      }
  385.      break;
  386.       case GL_UNSIGNED_SHORT:
  387.      k = 0;
  388.      for (i=0;i<heightout;i++) {
  389.         GLushort *usptr = (GLushort *) dataout
  390.                         + i * rowstride
  391.                 + packskiprows * rowstride
  392.                 + packskippixels * components;
  393.         for (j=0;j<widthout*components;j++) {
  394.            *usptr++ = (GLushort) tempout[k++];
  395.         }
  396.      }
  397.      break;
  398.       case GL_SHORT:
  399.      k = 0;
  400.      for (i=0;i<heightout;i++) {
  401.         GLshort *sptr = (GLshort *) dataout
  402.                       + i * rowstride
  403.               + packskiprows * rowstride
  404.               + packskippixels * components;
  405.         for (j=0;j<widthout*components;j++) {
  406.            *sptr++ = (GLshort) tempout[k++];
  407.         }
  408.      }
  409.      break;
  410.       case GL_UNSIGNED_INT:
  411.      k = 0;
  412.      for (i=0;i<heightout;i++) {
  413.         GLuint *uiptr = (GLuint *) dataout
  414.                       + i * rowstride
  415.               + packskiprows * rowstride
  416.               + packskippixels * components;
  417.         for (j=0;j<widthout*components;j++) {
  418.            *uiptr++ = (GLuint) tempout[k++];
  419.         }
  420.      }
  421.      break;
  422.       case GL_INT:
  423.      k = 0;
  424.      for (i=0;i<heightout;i++) {
  425.         GLint *iptr = (GLint *) dataout
  426.                     + i * rowstride
  427.             + packskiprows * rowstride
  428.             + packskippixels * components;
  429.         for (j=0;j<widthout*components;j++) {
  430.            *iptr++ = (GLint) tempout[k++];
  431.         }
  432.      }
  433.      break;
  434.       case GL_FLOAT:
  435.      k = 0;
  436.      for (i=0;i<heightout;i++) {
  437.         GLfloat *fptr = (GLfloat *) dataout
  438.                       + i * rowstride
  439.               + packskiprows * rowstride
  440.               + packskippixels * components;
  441.         for (j=0;j<widthout*components;j++) {
  442.            *fptr++ = tempout[k++];
  443.         }
  444.      }
  445.      break;
  446.       default:
  447.      return GLU_INVALID_ENUM;
  448.    }
  449.  
  450.  
  451.    /* free temporary image storage */
  452.    free( tempin );
  453.    free( tempout );
  454.  
  455.    return 0;
  456. }
  457.  
  458.  
  459.  
  460. /*
  461.  * Return the largest k such that 2^k <= n.
  462.  */
  463. static GLint ilog2( GLint n )
  464. {
  465.    GLint k;
  466.  
  467.    if (n<=0) return 0;
  468.    for (k=0; n>>=1; k++) ;
  469.    return k;
  470. }
  471.  
  472.  
  473.  
  474. /*
  475.  * Find the value nearest to n which is also a power of two.
  476.  */
  477. static GLint round2( GLint n )
  478. {
  479.    GLint m;
  480.  
  481.    for (m=1; m<n; m*=2)
  482.      ;
  483.  
  484.    /* m>=n */
  485.    if (m-n <= n-m/2) {
  486.       return m;
  487.    }
  488.    else {
  489.       return m/2;
  490.    }
  491. }
  492.  
  493.  
  494. /*
  495.  * Given an pixel format and datatype, return the number of bytes to
  496.  * store one pixel.
  497.  */
  498. static GLint bytes_per_pixel( GLenum format, GLenum type )
  499. {
  500.    GLint n, m;
  501.  
  502.    switch (format) {
  503.       case GL_COLOR_INDEX:
  504.       case GL_STENCIL_INDEX:
  505.       case GL_DEPTH_COMPONENT:
  506.       case GL_RED:
  507.       case GL_GREEN:
  508.       case GL_BLUE:
  509.       case GL_ALPHA:
  510.       case GL_LUMINANCE:
  511.      n = 1;
  512.      break;
  513.       case GL_LUMINANCE_ALPHA:
  514.      n = 2;
  515.      break;
  516.       case GL_RGB:
  517.      n = 3;
  518.      break;
  519.       case GL_RGBA:
  520.      n = 4;
  521.      break;
  522.       default:
  523.      n = 0;
  524.    }
  525.  
  526.    switch (type) {
  527.       case GL_UNSIGNED_BYTE:    m = sizeof(GLubyte);    break;
  528.       case GL_BYTE:        m = sizeof(GLbyte);    break;
  529.       case GL_BITMAP:        m = 1;            break;
  530.       case GL_UNSIGNED_SHORT:    m = sizeof(GLushort);    break;
  531.       case GL_SHORT:        m = sizeof(GLshort);    break;
  532.       case GL_UNSIGNED_INT:    m = sizeof(GLuint);    break;
  533.       case GL_INT:        m = sizeof(GLint);    break;
  534.       case GL_FLOAT:        m = sizeof(GLfloat);    break;
  535.       default:            m = 0;
  536.    }
  537.  
  538.    return n * m;
  539. }
  540.  
  541.  
  542.  
  543. /*
  544.  * WARNING: This function isn't finished and has never been tested!!!!
  545.  */
  546. GLint gluBuild1DMipmaps( GLenum target, GLint components,
  547.                          GLint width, GLenum format,
  548.                          GLenum type, const void *data )
  549. {
  550.    GLubyte *texture;
  551.    GLint levels, max_levels;
  552.    GLint new_width, max_width;
  553.    GLint i, j, k, l;
  554.  
  555.    glGetIntegerv( GL_MAX_TEXTURE_SIZE, &max_width );
  556.    max_levels = ilog2( max_width ) + 1;
  557.  
  558.    /* Compute how many mipmap images to make */
  559.    levels = ilog2( width ) + 1;
  560.    if (levels>max_levels) {
  561.       levels = max_levels;
  562.    }
  563.  
  564.    new_width = 1 << (levels-1);
  565.  
  566.    texture = (GLubyte *) malloc( new_width * components );
  567.    if (!texture) {
  568.       return GLU_OUT_OF_MEMORY;
  569.    }
  570.  
  571.    if (width != new_width) {
  572.       /* initial rescaling */
  573.       switch (type) {
  574.      case GL_UNSIGNED_BYTE:
  575.         {
  576.            GLubyte *ub_data = (GLubyte *) data;
  577.            for (i=0;i<new_width;i++) {
  578.           j = i * width / new_width;
  579.           for (k=0;k<components;k++) {
  580.              texture[i*components+k] = ub_data[j*components+k];
  581.           }
  582.            }
  583.         }
  584.         break;
  585.      default:
  586.         /* Not implemented */
  587.         return GLU_ERROR;
  588.       }
  589.    }
  590.  
  591.    /* generate and load mipmap images */
  592.    for (l=0;l<levels;l++) {
  593.       glTexImage1D( GL_TEXTURE_1D, l, components, new_width, 0,
  594.             format, GL_UNSIGNED_BYTE, texture );
  595.  
  596.       /* Scale image down to 1/2 size */
  597.       new_width = new_width / 2;
  598.       for (i=0;i<new_width;i++) {
  599.      for (k=0;k<components;k++) {
  600.         GLint sample1, sample2;
  601.         sample1 = (GLint) texture[i*2*components+k];
  602.         sample2 = (GLint) texture[(i*2+1)*components+k];
  603.         texture[i*components+k] = (GLubyte) ((sample1 + sample2) / 2);
  604.      }
  605.       }
  606.    }
  607.  
  608.    free( texture );
  609.  
  610.    /* make sure remaining mipmap levels are removed */
  611.    for (l=levels;l<max_levels;l++) {
  612.       glTexImage1D( GL_TEXTURE_1D, l, components, 0, 0,
  613.             format, GL_UNSIGNED_BYTE, NULL );
  614.    }
  615.  
  616.    return 0;
  617. }
  618.  
  619.  
  620.  
  621. GLint gluBuild2DMipmaps( GLenum target, GLint components,
  622.                          GLint width, GLint height, GLenum format,
  623.                          GLenum type, const void *data )
  624. {
  625.    GLint w, h, maxsize;
  626.    void *image, *newimage;
  627.    GLint neww, newh, level, bpp;
  628.    int error;
  629.  
  630.    glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxsize );
  631.  
  632.    w = round2( width );
  633.    if (w>maxsize) {
  634.       w = maxsize;
  635.    }
  636.    h = round2( height );
  637.    if (h>maxsize) {
  638.       h = maxsize;
  639.    }
  640.  
  641.    bpp = bytes_per_pixel( format, type );
  642.    if (bpp==0) {
  643.       /* probably a bad format or type enum */
  644.       return GLU_INVALID_ENUM;
  645.    }
  646.  
  647.    if (w!=width || h!=height) {
  648.       /* must rescale image to get "top" mipmap texture image */
  649.       image = malloc( (w+4) * h * bpp );
  650.       if (!image) {
  651.      return GLU_OUT_OF_MEMORY;
  652.       }
  653.       error = gluScaleImage( format, width, height, type, data,
  654.                  w, h, type, image );
  655.       if (error) {
  656.      return error;
  657.       }
  658.    }
  659.    else {
  660.       image = (void *) data;
  661.    }
  662.  
  663.    level = 0;
  664.    while (1) {
  665.       glTexImage2D( target, level, components, w, h, 0, format, type, image );
  666.  
  667.       if (w==1 && h==1)  break;
  668.  
  669.       neww = (w<2) ? 1 : w/2;
  670.       newh = (h<2) ? 1 : h/2;
  671.       newimage = malloc( (neww+4) * newh * bpp );
  672.       if (!newimage) {
  673.      return GLU_OUT_OF_MEMORY;
  674.       }
  675.  
  676.       error =  gluScaleImage( format, w, h, type, image,
  677.                   neww, newh, type, newimage );
  678.       if (error) {
  679.      return error;
  680.       }
  681.  
  682.       if (image!=data) {
  683.      free( image );
  684.       }
  685.       image = newimage;
  686.  
  687.       w = neww;
  688.       h = newh;
  689.       level++;
  690.    }
  691.  
  692.    if (image!=data) {
  693.       free( image );
  694.    }
  695.  
  696.    return 0;
  697. }
  698.  
  699.